package com.hewanning.toy.play.util;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.hewanning.toy.play.common.RedisKey;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @author robin_he
 * @date 2020/1/6
 */

public class JwtHelper {

    private Long EXPIRATION_TIME;
    private String SECRET;
    private final String TOKEN_PREFIX = "Bearer";
    private final String HEADER_STRING = "Authorization";
    private RedisUtils redisUtils;

    public JwtHelper(String secret, long expire, RedisUtils redisUtils) {
        this.EXPIRATION_TIME = expire;
        this.SECRET = secret;
        this.redisUtils = redisUtils;
        System.out.println("正在初始化Jwthelper，expire=" + expire);
    }

    public JSONObject generateToken(Map<String, Object> claims) {
        Object loginName = claims.get("loginName");
        String username = loginName.toString();
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.SECOND, EXPIRATION_TIME.intValue());
        Date d = c.getTime();
        String jwt = Jwts.builder()
                .setClaims(claims)
                .setExpiration(d)
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
        JSONObject json = new JSONObject();
        String token = TOKEN_PREFIX + " " + jwt;
        json.put("token", token);
        json.put("token-type", TOKEN_PREFIX);
        json.put("expire-time", new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(d));
        redisUtils.set(RedisKey.TOKEN + username, token, EXPIRATION_TIME);
        return json;
    }

    public Map<String, Object> validateTokenAndGetClaims(HttpServletRequest request) {
        String token = request.getHeader(HEADER_STRING);
        System.out.println("token is:" + token);
        if (token == null) {
            return null;
        }
        Map<String, Object> body = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
                .getBody();
        Object loginName = body.get("loginName");
        String username = loginName.toString();
        String redisToken = redisUtils.get(RedisKey.TOKEN + username, String.class);
        if (!token.equals(redisToken)) {
            return null;
        }
        return body;
    }

    public void logout(HttpServletRequest request) {
        Map<String, Object> body = validateTokenAndGetClaims(request);
        if (CollUtil.isNotEmpty(body)){
            Object loginName = body.get("loginName");
            String username = loginName.toString();
            redisUtils.del(RedisKey.TOKEN + username);
        }

    }
}